package com.bsf.sonar;

import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.val;
import org.jsoup.Jsoup;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @author: chejiangyi
 * @create: 2019-05-10 08:58
 **/
@Component
public class Sonar {
    @Value("${sonar.url}")
    private String sonarUrl;
    @Value("${sonar.parseformat}")
    private String sonarParseformat;
    private String releateApi="$sonarurl/api/measures/search?projectKeys=$projectName&metricKeys=alert_status,bugs,reliability_rating,vulnerabilities,security_rating,code_smells,sqale_rating,duplicated_lines_density,coverage,ncloc,ncloc_language_distribution";
    public String run(String projectName)
    {
        try {
            val doc = Jsoup.connect(releateApi.replace("$sonarurl", sonarUrl).replace("$projectName", projectName))
                    .header("Accept", "*/*")
                    .header("Accept-Encoding", "gzip, deflate")
                    .header("Accept-Language","zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3")
                    .header("Content-Type", "application/json;charset=UTF-8")
                    .ignoreContentType(true);
            val html = doc.get().body().html();
            JsonResult json = JSON.parseObject(html, JsonResult.class);

            if (json.measures.size() > 0) {
                ParseResult r = new ParseResult();
                json.measures.forEach(item -> {
                    if (item.metric.equals("bugs")) {
                        r.bug = item.value;
                    } else if (item.metric.equals("vulnerabilities")) {
                        r.leak = item.value;
                    } else if (item.metric.equals("code_smells")) {
                        r.code_smell = item.value;
                    } else if (item.metric.equals("coverage")) {
                        r.coverage = item.value;
                    } else if (item.metric.equals("duplicated_lines_density")) {
                        r.density = item.value;
                    } else if (item.metric.equals("alert_status")) {
                        r.status = item.value;
                    }
                });
                val sonarResult = new String[]{sonarParseformat};
                Arrays.stream(r.getClass().getDeclaredFields()).forEach(c -> {
                    c.setAccessible(true);
                    try {
                        sonarResult[0] = sonarResult[0].replace("{$" + c.getName() + "}", c.get(r).toString());
                    }catch (Exception e)
                    {}
                });
                return sonarResult[0];
            }
            throw new Exception("访问异常");
        }
        catch (Exception e)
        {
            return "访问sonar出错:"+e.getMessage();
        }
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    private static class JsonResult
    {
        private ArrayList<Metric> measures = new ArrayList<>();
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    private static class Metric
    {
        private String metric;
        private Object value;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    private static class ParseResult
    {
        private Object bug="[未知]";
        private Object leak="[未知]";
        private Object code_smell="[未知]";
        private Object coverage="[未知]";
        private  Object density="[未知]";
        private  Object status="[未知]";
    }
}
